package hotel.compare.oversea.controller;

import hotel.base.oversea.controller.BaseController;
import hotel.base.oversea.utils.*;
import hotel.compare.oversea.config.service.RedisService;
import hotel.compare.oversea.entity.master.CompareHotel;
import hotel.compare.oversea.entity.meituan.MtHotelGoods;
import hotel.compare.oversea.mapper.master.CompareHotelMapper;
import hotel.compare.oversea.mapper.meituan.MtHotelGoodsMapper;
import hotel.compare.oversea.service.MeituanSpiderService;
import hotel.compare.oversea.vo.meituan.MtHotelRoomVO;
import hotel.compare.oversea.vo.meituan.MtHotelVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutionException;

/**
 * 美团爬虫测试
 * @author Zhang·JZ
 * @date 2020-09-18
 */
@Slf4j
@RestController
@RequestMapping("/meituanSpider")
@Api(value = "MeituanSpiderController", tags = {"爬虫接口"})
public class MeituanSpiderController extends BaseController {

    @Autowired
    private MeituanSpiderService meituanSpiderService;

    @Autowired
    private CompareHotelMapper compareHotelMapper;

    @Autowired
    private MtHotelGoodsMapper mtHotelGoodsMapper;

    @Autowired
    private RedisService redisService;

    private CloseableHttpClient httpClient = null;
    private CloseableHttpResponse response = null;
    // 创建httpGet远程连接实例
    private HttpGet httpGet = null;

    private int openSpider = 0; //0 默认； 1：开； 2：关
    private String cookie;

    private String openMtSpiderKey = "open_meituan_spider_hotel_key";

    private String cookieKey = "meituan_spider_cookies_key";

    private List<MtHotelGoods> mtHotelGoods = new ArrayList<>();


    @PostMapping("/closeSpider")
    public Result closeSpider(){
        openSpider = 2;
        return  new Result<>("已关闭爬虫！！！");
    }


    /**
     * 1:先配置cookies
     * 2:在开启美团爬取接口
     * @param cookies
     * @return
     */
    @PostMapping("/setCookiesToSpider")
    public Result setCookiesToSpider(@RequestBody(required = false) String cookies){
        if(ObjectUtils.isEmpty(cookies)){
            log.info("setCookiesToSpider——————>>> cookies 参数为空！！！");
            return new Result<>("cookies 参数为空！！！");
        }
        redisService.set(cookieKey,cookies);
        return  new Result<>(cookies);
    }




    /**
     * 爬取美团酒店下单前校验
     * 根据美团酒店id-room
     */
    @PostMapping("/meituanSpiderHotelGoodsNoticeByMtHotelRoom")
    public void meituanSpiderHotelGoodsNoticeByMtHotelRoom(@RequestBody(required = false) String mtHotelGoodsJson){
        log.info("jsonObject>>>>>{}",mtHotelGoodsJson);
        if(ObjectUtils.isEmpty(mtHotelGoodsJson)){
            log.info("meituanSpiderHotelGoodsNoticeByMtHotelRoom——————>>> 参数串为空！！！");
            return;
        }
        if(redisService.exists(cookieKey)){
            cookie = (String) redisService.get(cookieKey);
        }

        if(ObjectUtils.isEmpty(cookie)){
            log.info("meituanSpiderHotelGoodsNoticeByMtHotelRoom——————>>> cookie 参数串为空！！！");
            return;
        }
        List<MtHotelGoods> mtHotelGoodsList = new ArrayList<>();
        Map hotelMap = new HashMap();
        try {
            hotelMap = JacksonUtil.parse(mtHotelGoodsJson,Map.class);

            Iterator entries = hotelMap.entrySet().iterator();
            while (entries.hasNext()) {
                MtHotelGoods mtHotelGoodsNew = new MtHotelGoods();
                Map.Entry entry = (Map.Entry) entries.next();
                String hotelId = (String)entry.getKey();

                mtHotelGoodsNew.setMtHotelId(hotelId);

                List<String> goodsIdList = (List<String>) entry.getValue();
                if(!goodsIdList.isEmpty() && goodsIdList.size()>0){
                    goodsIdList.forEach(goodsId->{
                        mtHotelGoodsNew.setMtGoodsId(goodsId);
                        mtHotelGoodsNew.setMtGoodsName("美团爬虫");
                    });
                }

                mtHotelGoodsList.add(mtHotelGoodsNew);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(!mtHotelGoodsList.isEmpty() && mtHotelGoodsList.size()>0){
            try {
                boolean ret = meituanSpiderService.meituanSpiderHotelGoods(mtHotelGoodsList,cookie);
                log.info("meituanSpiderHotelGoodsNoticeByMtHotelRoom——————ret>>>{}",ret);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 爬取美团酒店下单前校验
     */
    @PostMapping("/meituanSpiderHotelGoodsNotice")
//    public void meituanSpiderHotelGoodsNotice(@RequestBody(required = false) String cookies) throws ExecutionException, InterruptedException {
    public void meituanSpiderHotelGoodsNotice() throws ExecutionException, InterruptedException {

        log.info("meituanSpiderHotelGoodsNotice--进入美团爬虫----->>>>>");
        if(redisService.exists(cookieKey)){
            cookie = (String) redisService.get(cookieKey);
        }
        log.info("meituanSpiderHotelGoodsNotice--cookie----->>>>>{}",cookie);

        if(ObjectUtils.isEmpty(cookie)){
            log.info("meituanSpiderHotelGoodsNoticeByMtHotelRoom——————>>> cookie 参数串为空！！！");
            return;
        }


        if(openSpider == 0){
            openSpider = 1;
            redisService.set(openMtSpiderKey,openSpider);
        }
        log.info("meituanSpiderHotelGoodsNotice--openSpider----->>>>>{}",openSpider);
        while (openSpider==1){
//            Example example = new Example(MtHotelGoods.class);
//            example.setOrderByClause("id desc limit 1");
//            mtHotelGoods = mtHotelGoodsMapper.selectByExample(example);

//            mtHotelGoods = mtHotelGoodsMapper.selectAll();

            log.info("mtHotelGoods------->>>>>{}",mtHotelGoods.size());
            //判断是否为空
            if(mtHotelGoods.isEmpty() || mtHotelGoods.size() == 0){
                mtHotelGoods = mtHotelGoodsMapper.findSwitchCreateRoomListByMeituanGoods();
            }

            if(!mtHotelGoods.isEmpty() && mtHotelGoods.size()>0){
                meituanSpiderService.meituanSpiderHotelGoods(mtHotelGoods,cookie);
            }

            log.info("meituanSpiderHotelGoodsNotice--美团爬虫一轮完成，准备开始递归----->>>>>");
            //递归
            meituanSpiderHotelGoodsNotice();
        }

    }

    /**
     * 爬取美团酒店房价、房态并做通知
     */
    @PostMapping("/meituanSpiderHotelNotice")
    public void meituanSpiderHotelNotice(@RequestBody(required = false) String cookies) throws ExecutionException, InterruptedException {
        List<String> poiIdList = new ArrayList<>();
        List<CompareHotel> compareHotelList = new ArrayList<>();
        CompareHotel compareHotel = new CompareHotel();
        compareHotel.setIsCreateSub(1);

        Example example = new Example(CompareHotel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("isCreateSub",1);
        compareHotelList = compareHotelMapper.selectByExample(example);
        if(!compareHotelList.isEmpty() && compareHotelList.size()>0){
            compareHotelList.forEach(compareHotelNew->{
                poiIdList.add(compareHotelNew.getMtHotelId());
            });
        }


        if(!poiIdList.isEmpty() && poiIdList.size()>0){

            meituanSpiderService.meituanSpiderHotel(poiIdList,cookies);
        }

    }

    public void setMeituanHeaders(String url){
        // 通过址默认配置创建一个httpClient实例
        httpClient = HttpClients.createDefault();
        httpGet = new HttpGet(url);
        // 传输的类型
        httpGet.addHeader("cookie", "JSESSIONID=node01hknoqjk1hx3x26v570tae9na860875.node0; _lxsdk_cuid=17278dc633fc8-04e7e564812aa2-6373664-1fa400-17278dc633fc8; ci=62; iuuid=AFD13B9A1E82B29623986C539ED7B14D790CBF6EF25785B8B8282129B48091FA; cityname=%E5%8E%A6%E9%97%A8; _lxsdk=AFD13B9A1E82B29623986C539ED7B14D790CBF6EF25785B8B8282129B48091FA; Hm_lvt_f66b37722f586a240d4621318a5a6ebe=1595483024; __utma=211559370.1262968389.1595483024.1595483024.1595483024.1; __utmz=211559370.1595483024.1.1.utmcsr=baidu|utmccn=baidu|utmcmd=organic|utmcct=zt_search; i_extend=C085021465567978133866654328195751632659_g1E_c3_e13940464909580632571_a%e6%b9%be%e6%82%a6%e5%9f%8e_b400203_o1_dhotelpoitagb_k1001_f192659289Gempty__xhotelhomepage__yselect__zhour; IJSESSIONID=193w3q54ys0tz1hr89t2z4udsx; _ga=GA1.2.1262968389.1595483024; uuid=e06f25933ece4d11b968.1600413326.1.0.0; mtcdn=K; userTicket=IxkLkGdSXtROdHRlSfuqIHwyHhwVbowRbSsHtWnq; u=219845832; n=zhangjz918; lt=DkJ43oS8RkmX0HY8AjSveWkhgk4AAAAAkAsAABeF3GuwKcauaMYQlRWH1_ihQfhyMThAyVvPD35dL6SFEecybEy9FMbrXt2RbrlqDQ; mt_c_token=DkJ43oS8RkmX0HY8AjSveWkhgk4AAAAAkAsAABeF3GuwKcauaMYQlRWH1_ihQfhyMThAyVvPD35dL6SFEecybEy9FMbrXt2RbrlqDQ; token=DkJ43oS8RkmX0HY8AjSveWkhgk4AAAAAkAsAABeF3GuwKcauaMYQlRWH1_ihQfhyMThAyVvPD35dL6SFEecybEy9FMbrXt2RbrlqDQ; lsu=; token2=DkJ43oS8RkmX0HY8AjSveWkhgk4AAAAAkAsAABeF3GuwKcauaMYQlRWH1_ihQfhyMThAyVvPD35dL6SFEecybEy9FMbrXt2RbrlqDQ; isid=2BC0392767D49633E70F118C29AE0C5E; logintype=normal; oops=DkJ43oS8RkmX0HY8AjSveWkhgk4AAAAAkAsAABeF3GuwKcauaMYQlRWH1_ihQfhyMThAyVvPD35dL6SFEecybEy9FMbrXt2RbrlqDQ; unc=zhangjz918; firstTime=1600413391781; _lx_utm=utm_source%3Dbaidu%26utm_campaign%3Dbaidu%26utm_medium%3Dorganic%26utm_content%3Dzt_search; bzacctid=69333241; ssoLogin=HHB1688; fxUserId=22082; fxUserName=HHB1688; dtorId=12350; bsid=SXkV9X9pN49Eirq4SSZ1qG1yIaIXO8sFjZqnjZWYZw4eBnxvS_F3iVtNw8bwG9VxXIyU5tNA9FGp15feDrvFmg; __mta=216308393.1598634255513.1600754482133.1600754490725.170; _lxsdk_s=174b466efc7-4a5-a3c-330%7C%7C5");
        httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36");
        httpGet.addHeader("referer", "https://mf.meituan.com/");
    }

    /**
     * 获取当日爬取的酒店列表
     *
     * @return
     */
    @PostMapping("/getMeituanSpiderHotelList")
    @ApiOperation(value = "获取当日爬取的酒店列表")
    public String getMeituanSpiderHotelList() {
        log.info("<<<<<<<<<<<<开始爬取酒店列表 >>>>>>>>>>>");
        String url = "https://mf.meituan.com/fenxiao-web/hotel/list?utm_medium=pc&version_name=999.9&cateId=20&attr_28=129&cityId=1&roomNum=1&sort=solds&startDay=20200918&endDay=20200919&offset=0&limit=20&uuid=977&userId=22082";
        String result = "";
        try {

            setMeituanHeaders(url);
            // 设置配置请求参数
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
                    .setConnectionRequestTimeout(35000)// 请求超时时间
                    .setSocketTimeout(60000)// 数据读取超时时间
                    .build();
            // 为httpGet实例设置配置
            httpGet.setConfig(requestConfig);
            // 执行get请求得到返回对象
            response = httpClient.execute(httpGet);
            // 通过返回对象获取返回数据
            HttpEntity entity = response.getEntity();
            // 通过EntityUtils中的toString方法将结果转换为字符串
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }


    /**
     * 获取酒店详情
     *
     * @return
     */
    @PostMapping("/getMeituanSpiderHotelDetail")
    @ApiOperation(value = "获取酒店详情")
    public String getMeituanSpiderHotelDetail() {
        log.info("<<<<<<<<<<<<开始爬取酒店列表 >>>>>>>>>>>");
        String url = "https://mf.meituan.com/fenxiao-web/hotel/detail?utm_medium=pc&version_name=999.9&cateId=20&attr_28=129&poiId=350403&roomNum=1&startDay=20200922&endDay=20200923";
        String result = "";
        try {
            setMeituanHeaders(url);
            // 设置配置请求参数
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
                    .setConnectionRequestTimeout(35000)// 请求超时时间
                    .setSocketTimeout(60000)// 数据读取超时时间
                    .build();
            // 为httpGet实例设置配置
            httpGet.setConfig(requestConfig);
            // 执行get请求得到返回对象
            response = httpClient.execute(httpGet);
            // 通过返回对象获取返回数据
            HttpEntity entity = response.getEntity();
            // 通过EntityUtils中的toString方法将结果转换为字符串
            result = EntityUtils.toString(entity);
            Map<String,Object> retMap = JacksonUtil.parse(result,Map.class);
            MtHotelVO mtHotelVo = JacksonUtil.objToBean(retMap.get("data"), MtHotelVO.class);
            if(!ObjectUtils.isEmpty(mtHotelVo)){
                List<MtHotelRoomVO> mtHotelRoomVoList = mtHotelVo.getHotelGoodsInfoVOList();
                log.info("mtHotelRoomVoList>>>>>>>>{}",mtHotelRoomVoList);
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}


